package cn.joyfulmedia.common.dto;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import cn.joyfulmedia.common.log.CustomLogger;
import cn.joyfulmedia.common.log.CustomLoggerFactory;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;

/**
 * http api 层返回协议封装
 * Created by yujun on 2016/9/5.
 */
public class BaseResponse<T> implements Serializable {
    private static final CustomLogger log = CustomLoggerFactory.getLogger(ResultDO.class);
    private static final CustomLogger interfaceLog = CustomLoggerFactory.getLogger("cn.joyfulmedia.interface.access.log");

    /**
     * 错误码
     */
    private int code = 0;
    /**
     * 异常信息
     */
    private String msg;
    /**
     * 返回结果集
     */
    private T data;
    /**
     * 开始时间 ms
     */
    @JSONField(serialize = false)
    private long startTime = new Date().getTime();

    /**
     * 私有化该构造函数,空response无意义
     */
    private BaseResponse() {

    }

    /**
     * 构造函数
     *
     * @param code 返回状态信息
     */
    private BaseResponse(BeanEnumCode code) {
        this.code = code.getCode();
        this.msg = code.getMessage();
    }

    /**
     * 实例化对象
     *
     * @param <T> data泛型
     * @return response
     */
    public static <T> BaseResponse<T> buildResult() {
        return new BaseResponse<>(BeanEnumCode.SUCCESS);
    }

    /**
     * 用于给结果集按照是否有callback的方式封装返回
     * <p>
     * 该方法废除,使用 {@link #getJsonpResult(BaseResponse, String, HttpServletRequest)},便于统一输出接口日志
     *
     * @param response 返回数据结果集
     * @param callback callback参数
     * @return 封装后的数据
     */
    @Deprecated
    public static String getJsonpResult(BaseResponse response, String callback) {
        if (StringUtils.isNotEmpty(callback)) {
            return callback + "(" + JSON.toJSONString(response) + ")";
        } else {
            return JSON.toJSONString(response);
        }
    }

    /**
     * 于给结果集按照是否有callback的方式封装返回,并输出接口日志
     *
     * @param response 返回数据结果集
     * @param callback callback参数
     * @param request  请求体
     * @return 封装后的数据
     */
    public static String getJsonpResult(BaseResponse response, String callback, HttpServletRequest request) {
        if (response.getCode() != BeanEnumCode.SUCCESS.getCode()) {
            String method = request.getMethod();
            String url = request.getRequestURI();
            final long consumeTime = new Date().getTime() - response.getStartTime();
            /**
             * 从左到右 [] 代表含义:[方法] [URI] [CODE] [耗时] [head param] [request param] [response param]
             */
            interfaceLog.info("[{}] [{}] [{}] [{}]", method, url, response.getCode(), consumeTime);
        }
        if (StringUtils.isNotEmpty(callback)) {
            return callback + "(" + JSON.toJSONString(response) + ")";
        } else {
            return JSON.toJSONString(response);
        }
    }

    /**
     * 设置异常code
     *
     * @param code     错误码
     * @param msg      错误信息
     * @param response 返回体
     */
    private static void setCode(int code, String msg, BaseResponse<?> response) {
        response.setCode(code);
        response.setMsg(msg == null ? "" : msg);
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }

}
